#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
Created on 2012-11-7

@author: nibo
'''
import commands
import os
from setting import SVN_BIN, SAM_SOURCE_PATH, SIM_SOURCE_PATH, PROFILE_LOCAL_PATH, NMS_LOCAL_PATH,\
SHELL_LOCAL_PATH,ANT_BIN, ANT_BUILD_PATH, SIM_BUILD_NAME, SAM_GZ_PATH, CREATE_GZ_PATH, \
SIM_GZ_PATH, SIM_GZ_NAME, CONFIG_ITEM, HIBERNATE_CONFIG_NAME, JAVA_FRAMEWORK_SOURCE_PATH,\
SIM_WAR_NAME, SIM_SVN_SOURCE_PATH, JAVA_FRAMEWORK_SVN_SOURCE_PATH, BMS_SAM_SVN_SOURCE_PATH,\
BMS_SAM_BUILD_NAME, BMS_SAM_WAR_NAME, BMS_NMS_SVN_PATH, BMS_SHELL_SVN_PATH, BMS_PROFILE_SVN_PATH,\
BMS_SAM_GZ_NAME, BMC_SAM_SVN_SOURCE_PATH, BMC_SAM_BUILD_NAME, BMC_SAM_WAR_NAME, BMC_NMS_SVN_PATH,\
BMC_SHELL_SVN_PATH, BMC_PROFILE_SVN_PATH, HIBERNATE_CONFIG_BMC_NAME, BMC_SAM_GZ_NAME

from setting import logger
import sys
import time
import shutil

def is_svn_bin():
    '''
        验证SVN bin目录是否存在,这是执行更新命令的关键
        存在返回True,不存在返回False
    '''
    if not os.path.isdir(SVN_BIN):
        logger.error('svn bin目录不存在,不能执行svn操作');
        return False
    return True

def is_ant_bin():
    '''
        验证Ant bin目录是否存在,这是执行源代码编译的关键
        存在返回True,不存在返回False
    '''
    if not os.path.isdir(ANT_BIN):
        logger.error('ant bin目录不存在,不能编译源代码')
        return False
    return True


def check_out(svn_path, local_path):
    '''
        从SVN检出指定目录下的文件或文件夹
    svn_path:svn源代码库路径
    local_path:本地svn目录
    '''
    if not is_svn_bin():
        return False
    
    if os.path.isdir(local_path):
        logger.info('清理目录:%s' % local_path)
        status, res = commands.getstatusoutput('rm -rf %s' % local_path)
        if status != 0:
            logger.info('清理目录失败:%s' % res)
            return False
    if not os.path.isdir(local_path):
        logger.info('创建目录:%s' % local_path)
        os.makedirs(local_path)
    svn_bin_path = os.path.join(SVN_BIN, 'svn')
    logger.info('检出文件...')
    logger.info('本地svn目录:%s' % local_path)
    logger.info('命令信息:%s co %s %s' % (svn_bin_path, svn_path, local_path))
    status, res = commands.getstatusoutput('%s co %s %s' %(svn_bin_path, svn_path, local_path))
    logger.info(res)
    if status == 0:
        logger.info('检出文件成功,目录:%s' % local_path)
        return True
    else:
        logger.error('检出文件失败,目录:%s' % local_path)
        return False

def check_out_profile(svn_path, local_path):
    '''
        从SVN检出指定目录下的文件或文件夹
    svn_path:svn源代码库路径
    local_path:本地svn目录
    '''
    if not is_svn_bin():
        return False
    
    if os.path.isdir(local_path):
        logger.info('清理目录:%s' % local_path)
        status, res = commands.getstatusoutput('rm -rf %s' % local_path)
        if status != 0:
            logger.info('清理目录失败:%s' % res)
            return False
    if not os.path.isdir(local_path):
        logger.info('创建目录:%s' % local_path)
        os.makedirs(local_path)
    svn_bin_path = os.path.join(SVN_BIN, 'svn')
    logger.info('检出文件...')
    logger.info('本地svn目录:%s' % local_path)
    logger.info('命令信息:%s co --depth=empty %s %s' % (svn_bin_path, svn_path, local_path))
    status, res = commands.getstatusoutput('%s co --depth=empty %s %s' %(svn_bin_path, svn_path, local_path))
    #切换目录
    os.chdir(local_path)
    logger.info('命令信息:%s update .profile' % svn_bin_path)
    status, res = commands.getstatusoutput('%s update .profile' % svn_bin_path)
    logger.info(res)
    if status == 0:
        logger.info('检出文件成功,目录:%s' % local_path)
        return True
    else:
        logger.error('检出文件失败,目录:%s' % local_path)
        return False
    
def do_war(ant_build_path, build_name, war_name):
    '''
        编译源代码,并打包成war包
    ant_build_path:ant的build.xml文件路径
    build_name:build文件名
    war_name:war包名称
    '''
    build_path = os.path.join(ant_build_path, build_name)
    if not is_ant_bin():
        return False
    if not os.path.isfile(build_path):
        logger.error('build文件不存在,%s' % build_path)
        return False
    
    #取得ant文件所在的目录
    war_path = os.path.join(ant_build_path, war_name);
    if os.path.isfile(war_path):
        logger.info('删除文件:%s' % war_path)
        os.remove(war_path)
        
    ant_bin_path = os.path.join(ANT_BIN, 'ant')
    logger.info('编译源代码,并生成war包...')
    logger.info('执行命名:%s -buildfile %s %s' %(ant_bin_path, build_path, 'war'))
    status, res = commands.getstatusoutput('%s -buildfile %s %s' %(ant_bin_path, build_path, 'war'))
    logger.info(res)
    if status == 0:
        logger.info('编译源代码成功,并生成war包')
        return True
    else:
        logger.error('编译源代码失败')
        return False
    
    
def is_module_gz_base_path(module_base_path):
    '''
        验证将要打GZ包的模块根目录是否存在,存在返回True
        不存在返回False
    '''
    if not os.path.isdir(module_base_path):
        logger.error('打GZ包的根目录不存在,路径:%s' % module_base_path)
        return False
    return True

def manager_base_directory_file(module_base_path, base_directory_name):
    '''
        1.清理模块目录下相关目录或文件,主要包括.profile文件,nms网管告警动态库,shell脚本
        2.创建相应的目录
        module_base_path:整个模块根目录路径
        base_directory_name:根目录文件夹名称
    '''
    if not is_module_gz_base_path(module_base_path):
        return False
    profile_path = os.path.join(module_base_path, '.profile')
    if os.path.isfile(profile_path):
        #删除.profile文件
        logger.info('删除文件:%s' % profile_path)
        os.remove(profile_path)
    nms_path = os.path.join(module_base_path, os.path.join(base_directory_name, 'nms'))
    if os.path.isdir(nms_path):
        #删除网管告警目录
        logger.info('删除目录:%s' % nms_path)
        shutil.rmtree(nms_path)
        logger.info('创建目录:%s' % nms_path)
        os.makedirs(nms_path)
    shell_path = os.path.join(module_base_path, os.path.join(base_directory_name, 'shell'))
    if os.path.isdir(shell_path):
        #删除shell脚本目录
        logger.info('删除目录:%s' % shell_path)
        shutil.rmtree(shell_path)
        logger.info('创建目录:%s' % shell_path)
        os.makedirs(shell_path)
    return True

def manager_module_directory_file(module_base_path, module_path):
    '''
        1.清理相应模块下tomcat目录的webapps目录,config目录
        2.重新创建对应目录
        module_base_path:整个模块根目录路径
        module_path:模块对应的tomcat路径
    '''
    if not is_module_gz_base_path(module_base_path):
        return False
    webapps_path = os.path.join(module_base_path, os.path.join(module_path ,'tomcat6/webapps'))
    if os.path.isdir(webapps_path):
        #删除tomcat目录下的webapps目录
        logger.info('删除目录:%s' % webapps_path)
        shutil.rmtree(webapps_path)
        logger.info('创建目录:%s' % webapps_path)
        os.makedirs(webapps_path)
    config_path = os.path.join(module_base_path, os.path.join(module_path ,'tomcat6/config'))
    if os.path.isdir(config_path):
        #删除tomcat目录下的config目录
        logger.info('删除目录:%s' % config_path)
        shutil.rmtree(config_path)
        logger.info('创建目录:%s' % config_path)
        os.makedirs(config_path)
    return True
    
def copy_directory(src, dst):
    '''
        递归拷贝目录下所有文件和目录到指定目录下,但不拷贝.svn目录
    '''
    if not os.path.isdir(src):
        logger.error('拷贝的原始目录不存在,目录:%s' % src)
        return False
    
    item_dir = os.listdir(src)
    if not os.path.exists(dst):
        logger.info('创建目录:%s' % dst)
        os.makedirs(dst)
        
    for dir_name in item_dir:
        if dir_name == '.svn':
            continue
        src_path = os.path.join(src, dir_name)
        if os.path.isfile(src_path):
            shutil.copy(src_path, dst);
        if os.path.isdir(src_path):
            dst_path = os.path.join(dst, dir_name)
            os.makedirs(dst_path)
            copy_directory(src_path, dst_path)
    
    return True

def copy_file(src, dst):
    '''
        拷贝文件到指定目录下,如果目录不存在由创建目录
    '''
    if not os.path.isfile(src):
        logger.error('拷贝的原始文件不存在,文件:%s' % src)
        return False
    if not os.path.exists(dst):
        logger.info('创建目录:%s' % dst)
        os.makedirs(dst)
        
    logger.info('拷贝文件:%s 至 目录:%s' % (src, dst))
    shutil.copy(src, dst)
    return True


def copy_config_file(source_src, dst, hibernate_name):
    '''
        拷贝配置文件到指定目录
    source_src:源文件目录
    dst:目标目录
    hibernate_name:hibernate文件名
    '''
    for config_name in CONFIG_ITEM:
        file_path = os.path.join(source_src, 'resources/config/' + config_name)
        copy_file(file_path, dst)
    
    return copy_file(os.path.join(source_src, 'resources/database/business/' + hibernate_name), dst)

def change_file_chmod(src_dir, mod):
    '''
        改变指定目录下所有文件的权限
    src_dir:目录
    mod:权限值
    '''
    if not os.path.isdir(src_dir):
        logger.error('目录不存在,目录:%s' % src_dir)
        return False
    logger.info('切换到目录:%s' % src_dir)
    os.chdir(src_dir)
    sts = commands.getstatusoutput('chmod %s *' % mod)[0]
    if sts == 0:
        logger.info('修改目录:%s 下所有文件权限成功' % src_dir)
        return True
    else:
        logger.error('修改目录:%s 下所有文件权限失败' % src_dir)
        return False
        
def do_gz(module_base_path, base_directory_name, tom_name, nms_name, shell_name, profile_path_svn, 
               nms_path_svn, shell_path_svn, module_source_path, hibernate_name, war_path, create_gz_path,
               gz_name):
    '''
        打GZ包的方法
    module_base_path:整个模块根目录路径
    base_directory_name:根目录文件夹名称
    tom_name:tomcat上层目录名,如:sam,sim
    nms_name:网管告警目录名
    shell_name:shell脚本目录名
    profile_path_svn:.profile文件的本地svn路径
    nms_path_svn:网管告警本地svn路径
    shell_path_svn:shell脚本本地svn路径
    module_source_path:模块源代码路径
    hibernate_name:hibernate文件名
    war_path:war包名称
    create_gz_path:存在gz包的路径
    gz_name:gz包名称
    '''
    #清理模块目录下相关目录或文件
    if not manager_base_directory_file(module_base_path, base_directory_name):
        return False
    
    tom_path = os.path.join(base_directory_name, tom_name)
    #清理sam模块tomcat目录下的webapps目录,config目录并重新创建对应目录
    if not manager_module_directory_file(module_base_path, tom_path):
        return False
    
    #拷贝svn本地.profile文件到打包模块的根目录下
    if not copy_file(profile_path_svn, module_base_path):
        return False
    
    #网管库名称不为空,拷贝相关文件到对应目录下
    if not nms_name is None:
        nms_path = os.path.join(module_base_path, os.path.join(base_directory_name, nms_name))
        logger.info('拷贝目录:%s 下所有文件或目录(除.svn目录) 至 目录:%s ' % (nms_path_svn, nms_path))
        #拷贝svn本地网管告警动态库文件到打包模块的nms目录下
        if not copy_directory(nms_path_svn, nms_path):
            return False
    
    shell_path = os.path.join(module_base_path, os.path.join(base_directory_name, shell_name))
    logger.info('拷贝目录:%s 下所有文件或目录(除.svn目录) 至 目录:%s ' % (shell_path_svn, shell_path))
    #拷贝svn本地shell脚本文件到打包模块shell脚本目录下
    if not copy_directory(shell_path_svn, shell_path):
        return False
    
    #改变shell目录下所有文件的权限
    if not change_file_chmod(shell_path, 700):
        return False
    
    #拷贝最新源代码config目录下的配置文件和hibernate的配置文件到tomcat/config目录下
    if not copy_config_file(module_source_path, os.path.join(module_base_path, os.path.join(tom_path, 'tomcat6/config')), hibernate_name):
        return False
    
    webapps_path = os.path.join(module_base_path, os.path.join(tom_path, 'tomcat6/webapps'))
    #拷贝编译好的war包到tomcat的webapps目录下
    if not copy_file(war_path, webapps_path):
        return False
    
    #切换到打gz包根目录
    logger.info('切换到目录:%s' % module_base_path)
    os.chdir(module_base_path)
    gz_file_path = os.path.join(create_gz_path, gz_name)
    
    if os.path.isfile(gz_file_path):
        logger.info('删除目录:%s 下的%s文件' % (create_gz_path, gz_name))
        os.remove(gz_file_path)
    
    logger.info('开始执行命令打gz包,命令:tar -zcvf %s %s %s' % (gz_file_path, base_directory_name, '.profile'))
    #执行命令打gz包
    sts, text = commands.getstatusoutput('tar -zcvf %s %s %s' % (gz_file_path, base_directory_name, '.profile'))
    logger.info(text)
    if sts == 0:
        logger.info('GZ包生成成功,生成路径:%s' % gz_file_path)
        return True
    else:
        logger.error('GZ包生成失败')
        return False
    
def print_command(arg):
    
    print('------------------Web打包脚本(Version 1.1)------------------------')
    print('usage: %s [args]' % arg)
    print('args:')
    print('-------------------------------------------')
    print('bmsgz(将群发器sam模块打包成gz包)')
    print('simgz(将群发器sim模块打包成gz包)')
    print('bmcgz(将控制中心sam模块打包成gz包)')
    print('bmswar(编译群发器sam源代码,并生成war包)')
    print('simwar(编译sim源代码,并生成war包)')
    print('bmcwar(编译控制中心sam源代码,并生成war包)')
    print('------------------Web打包脚本(Version 1.1)------------------------\n')

def do_main(args):
    if len(args) != 2:
        print_command(args[0])
        sys.exit(0)
        
    begin_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
    
    logger.info('-----------------------------Web打包脚本(Version 1.1)----------------------------------\n')
    if args[1] == 'bmswar':
        logger.info('------------BEGIN-编译群发器sam源代码,并打成war包(date:%s)----------------' % begin_time)
        if check_out(BMS_SAM_SVN_SOURCE_PATH, SAM_SOURCE_PATH) and check_out(JAVA_FRAMEWORK_SVN_SOURCE_PATH, JAVA_FRAMEWORK_SOURCE_PATH):
            do_war(ANT_BUILD_PATH, BMS_SAM_BUILD_NAME, BMS_SAM_WAR_NAME)
        end_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
        logger.info('-------------END-编译群发器sam源代码,并打成war包(date:%s)-----------------\n' % end_time)
        
    elif args[1] == 'simwar':
        logger.info('------------BEGIN-编译群发器sim源代码,并打成war包(date:%s)----------------' % begin_time)
        if check_out(SIM_SVN_SOURCE_PATH, SIM_SOURCE_PATH) and check_out(JAVA_FRAMEWORK_SVN_SOURCE_PATH, JAVA_FRAMEWORK_SOURCE_PATH):
            do_war(ANT_BUILD_PATH, SIM_BUILD_NAME, SIM_WAR_NAME)
                
        end_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
        logger.info('-------------END-编译群发器sim源代码,并打成war包(date:%s)-----------------\n' % end_time)
    
    elif args[1] == 'bmcwar':
        logger.info('------------BEGIN-编译控制中心sam源代码,并打成war包(date:%s)----------------' % begin_time)
        
        if check_out(BMC_SAM_SVN_SOURCE_PATH, SAM_SOURCE_PATH) and check_out(JAVA_FRAMEWORK_SVN_SOURCE_PATH, JAVA_FRAMEWORK_SOURCE_PATH):
            do_war(ANT_BUILD_PATH, BMC_SAM_BUILD_NAME, BMC_SAM_WAR_NAME)
            
        end_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
        logger.info('-------------END-编译控制中心sam源代码,并打成war包(date:%s)-----------------\n' % end_time)
        
    elif args[1] == 'bmsgz':
        logger.info('----------------BEGIN-将群发器sam模块打包成gz包(date:%s)-------------------' % begin_time)
        if check_out(BMS_SAM_SVN_SOURCE_PATH, SAM_SOURCE_PATH) and check_out(JAVA_FRAMEWORK_SVN_SOURCE_PATH, JAVA_FRAMEWORK_SOURCE_PATH):
            if do_war(ANT_BUILD_PATH, BMS_SAM_BUILD_NAME, BMS_SAM_WAR_NAME) and check_out(BMS_NMS_SVN_PATH, NMS_LOCAL_PATH) and \
            check_out(BMS_SHELL_SVN_PATH, SHELL_LOCAL_PATH) and check_out_profile(BMS_PROFILE_SVN_PATH, PROFILE_LOCAL_PATH):
            
                do_gz(SAM_GZ_PATH, 'bms', 'sam', 'nms', 'shell', os.path.join(PROFILE_LOCAL_PATH, '.profile'), NMS_LOCAL_PATH, SHELL_LOCAL_PATH, 
                      SAM_SOURCE_PATH, HIBERNATE_CONFIG_NAME, os.path.join(ANT_BUILD_PATH, BMS_SAM_WAR_NAME), CREATE_GZ_PATH, BMS_SAM_GZ_NAME)
                
        end_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
        logger.info('-----------------END-将群发器sam模块打包成gz包(date:%s)--------------------\n' % end_time)
        
    elif args[1] == 'simgz':
        logger.info('----------------BEGIN-将群发器sim模块打包成gz包(date:%s)-------------------' % begin_time)
        if check_out(SIM_SVN_SOURCE_PATH, SIM_SOURCE_PATH) and check_out(JAVA_FRAMEWORK_SVN_SOURCE_PATH, JAVA_FRAMEWORK_SOURCE_PATH):
            
            if do_war(ANT_BUILD_PATH, SIM_BUILD_NAME, SIM_WAR_NAME) and check_out(BMC_NMS_SVN_PATH, NMS_LOCAL_PATH) and \
            check_out(BMS_SHELL_SVN_PATH, SHELL_LOCAL_PATH) and check_out_profile(BMS_PROFILE_SVN_PATH, PROFILE_LOCAL_PATH):
                
                do_gz(SIM_GZ_PATH, 'bms', 'sim', 'nms', 'shell', os.path.join(PROFILE_LOCAL_PATH, '.profile'), NMS_LOCAL_PATH, SHELL_LOCAL_PATH, 
                      SIM_SOURCE_PATH, HIBERNATE_CONFIG_NAME, os.path.join(ANT_BUILD_PATH, SIM_WAR_NAME), CREATE_GZ_PATH, SIM_GZ_NAME)
                
        end_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
        logger.info('-----------------END-将群发器sim模块打包成gz包(date:%s)--------------------\n' % end_time)
    
    elif args[1] == 'bmcgz':
        logger.info('----------------BEGIN-将控制中心sam模块打包成gz包(date:%s)-------------------' % begin_time)
        if check_out(BMC_SAM_SVN_SOURCE_PATH, SAM_SOURCE_PATH) and check_out(JAVA_FRAMEWORK_SVN_SOURCE_PATH, JAVA_FRAMEWORK_SOURCE_PATH):
            
            if do_war(ANT_BUILD_PATH, BMC_SAM_BUILD_NAME, BMC_SAM_WAR_NAME) and check_out(BMS_NMS_SVN_PATH, NMS_LOCAL_PATH) and \
            check_out(BMC_SHELL_SVN_PATH, SHELL_LOCAL_PATH) and check_out_profile(BMC_PROFILE_SVN_PATH, PROFILE_LOCAL_PATH):
                
                do_gz(SAM_GZ_PATH, 'bmc', 'sam', 'nms', 'shell', os.path.join(PROFILE_LOCAL_PATH, '.profile'), NMS_LOCAL_PATH, SHELL_LOCAL_PATH, 
                      SAM_SOURCE_PATH, HIBERNATE_CONFIG_BMC_NAME, os.path.join(ANT_BUILD_PATH, BMC_SAM_WAR_NAME), CREATE_GZ_PATH, BMC_SAM_GZ_NAME)
                
        end_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
        logger.info('-----------------END-将控制中心sam模块打包成gz包(date:%s)--------------------\n' % end_time)
    else:
        print("Unknown command")
        print_command(sys.argv[0])
        
    logger.info('-----------------------------Web打包脚本(Version 1.1)----------------------------------\n\n\n\n')
    
if '__main__' == __name__:
    do_main(sys.argv)
        
        